package com.situ.mall.product.controller;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.situ.mall.common.util.Result;
import com.situ.mall.pojo.VO.IdVO;
import com.situ.mall.pojo.entity.product.Product;
import com.situ.mall.product.config.RedissonConfig;
import com.situ.mall.product.pojo.query.ProductQuery;
import com.situ.mall.product.service.IProductService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 商品 前端控制器
 * </p>
 *
 * @author CKX
 * @since 2024-10-10
 */
@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private IProductService productService;
    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("/list")
    public Result<Map<String, Object>> list(ProductQuery productQuery) {
        System.out.println("ProductController.list");
        Map<String, Object> map = productService.selectByPage(productQuery);
        return Result.ok(map);
    }

    @DeleteMapping("/deleteById/{id}")
    public Result deleteById(@PathVariable Integer id) {
        productService.removeById(id);
        return Result.ok("删除成功");
    }

    @DeleteMapping("/deleteAll/{ids}")
    public Result deleteAll(@PathVariable Integer[] ids) {
        productService.removeByIds(Arrays.asList(ids));
        return Result.ok("删除成功");
    }

    @PostMapping("/add")
    public Result add(@RequestBody Product product) {
        productService.save(product);
        return Result.ok("添加成功");
    }

    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable Integer id) {
        //Product product = productService.getById(id);
        Product product = productService.selectById(id);
        return Result.ok(product);
    }

    @PutMapping("/update")
    public Result update(@RequestBody Product product) {
        productService.update(product);
        return Result.ok("更新成功");
    }

    @PutMapping("/updateStatus/{id}/{status}")
    public Result updateStatus(@PathVariable Integer id, @PathVariable Integer status) {
        UpdateWrapper<Product> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id).set("status", status);
        productService.update(updateWrapper);
        return Result.ok("更新成功");
    }

    @GetMapping("/selectPromoProduct")
    public Result selectPromoProduct(String categoryName) {
        List<Product> list = productService.selectPromoProduct(categoryName);
        return Result.ok(list);
    }

    @GetMapping("/getHotProduct")
    public Result getHotProduct(String categoryName) {
        List<Product> list = productService.getHotProduct(categoryName);
        return Result.ok(list);
    }

    @GetMapping("/selectIds")
    public Result selectIds() {
        List<IdVO> list = productService.selectIds();
        return Result.ok(list);
    }

    @Autowired
    private RedissonConfig redissonConfig;

    @GetMapping("/hello")
    public String hello() {
        //1、获取一把锁，只要锁的名字一样，就是同一把锁
        RLock lock = redissonClient.getLock("my-lock");
        //2、加锁  阻塞式等待。默认加的锁都是30s,lockWatchdogTimeout = 30 * 1000 【看门狗默认时间】
        lock.lock();
        //1）锁的自动续期，如果业务超长，运行期间自动锁上新的30s。不用担心业务时间长，锁自动过期被删掉
        //只要占锁成功，就会启动一个定时任务【重新给锁设置过期时间，新的过期时间就是看门狗的默认时间】，每隔10秒都会自动再次续期，续成30秒
        //internalLockLeaseTime【看门狗时间】/3，10s
        //2）加锁的业务只要运行完成，就不会给当前锁续期，即使不手动解锁，锁默认会在30s内自动过期，不会产生死锁问题
        try {
            System.out.println("加锁成功，执行业务..." + Thread.currentThread().getId());
            try {
                TimeUnit.SECONDS.sleep(70);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            //3、解锁  假设解锁代码没有运行，Redisson会不会出现死锁
            System.out.println("释放锁..." + Thread.currentThread().getId());
            lock.unlock();
        }
        return "hello";
    }
}

